using UnityEngine;

public class PoolCue : MonoBehaviour
{
	public enum State
	{
		ROTATE,
		ROLL
	}

	public LayerMask layerMask;

	private Transform m_CueTrans;

	[SerializeField]
	private Transform m_FirePoint;

	[SerializeField]
	private Transform m_SidingPoint;

	[SerializeField]
	private float m_SidingPointOffset;

	private Vector3 m_CurrentSidingOffset;

	[SerializeField]
	private Vector2 m_SidingPointRange = new Vector2(0.006f, 0.01f);

	protected State m_state;

	protected Quaternion m_initalRot;

	protected Vector3 m_initalPos;

	protected float m_powerScalar = 1f;

	protected PoolBall m_targetBall;

	protected Vector3 m_targetPos;

	protected float m_CurRotAngle;

	protected Vector3 m_CurHitPoint;

	[SerializeField]
	protected Color m_GizmosColor;

	[SerializeField]
	[Range(0f, 0.02f)]
	private float m_R = 0.003f;

	public float CurRotAngle
	{
		set
		{
			m_CurRotAngle += value;
			m_CurRotAngle = MathTools.Roll(0f, 360f, m_CurRotAngle);
		}
	}

	public void Awake()
	{
		m_CueTrans = base.transform;
		m_initalPos = m_CueTrans.localPosition;
		m_initalRot = m_CueTrans.localRotation;
		m_CurRotAngle = 0f;
		m_SidingPointOffset = m_SidingPointRange.x;
	}

	protected Vector3 GetHitPoint()
	{
		if (Physics.Raycast(m_SidingPoint.position, m_FirePoint.forward, out RaycastHit hitInfo, float.MaxValue, 1 << LayerMask.NameToLayer("WhiteBall")))
		{
			return hitInfo.point;
		}
		BaseUIController.text.Show("The ray can not cast the white ball. need debug it");
		return Vector3.zero;
	}

	public void LateUpdate()
	{
		m_CueTrans.position = Pools.CueBall.transform.position;
		HandleRotate();
	}

	public void SetPowerScalar(float value)
	{
		m_powerScalar = value;
	}

	public void Fire()
	{
		Pools.CueBall.setTarget(m_targetBall, m_targetPos);
		float num = m_powerScalar;
		if (GameManager.Rules.firstRound && GameManager.GType != GameType.Mission)
		{
			num *= UnityEngine.Random.Range(1f, 1.5f);
		}
		Pools.CueBall.fireBall(num, m_FirePoint.forward, GetHitPoint());
		m_state = State.ROLL;
		m_CueTrans.parent = null;
		GameStatistics.MarkShot(1);
	}

	public void Rotate(float angle)
	{
		CurRotAngle = angle;
		m_CueTrans.RotateAround(Pools.CueBall.GetPosition(), Vector3.up, angle);
	}

	public void VerticalRotate(float angle)
	{
		m_FirePoint.localRotation = Quaternion.identity;
		m_FirePoint.localPosition = new Vector3(0f, 0f, -0.013f);
		m_FirePoint.RotateAround(Pools.CueBall.GetPosition(), m_CueTrans.right, angle);
		m_SidingPointOffset = Mathf.Lerp(m_SidingPointRange.x, m_SidingPointRange.y, angle / 90f);
		Siding(m_CurrentSidingOffset);
	}

	public void Reset()
	{
		m_CueTrans.localEulerAngles = new Vector3(0f, 90f, 0f);
	}

	public void Siding(Vector2 sideOffset)
	{
		m_CurrentSidingOffset = sideOffset;
		m_SidingPoint.localPosition = m_CurrentSidingOffset * m_SidingPointOffset;
	}

	private void HandleRotate()
	{
		if (!Pools.CueBall || !Pools.CueBall.sphereCollider)
		{
			return;
		}
		SphereCollider sphereCollider = Pools.CueBall.sphereCollider;
		Ray ray = new Ray(Pools.CueBall.transform.position, m_CueTrans.forward);
		float num = Pools.CueBall.GetRadius() - m_R;
		if (!Physics.SphereCast(ray, num - Mathf.Epsilon, out RaycastHit hitInfo, 1000f, layerMask.value))
		{
			return;
		}
		Vector3 point = hitInfo.point;
		BaseUIController.cueAndLines.GuidePointerAt(hitInfo.point, hitInfo.transform, hitInfo.normal, m_FirePoint.forward);
		Vector3 vector = point - sphereCollider.transform.position;
		point = sphereCollider.transform.position + vector.normalized * (vector.magnitude - num);
		Vector3 normal = hitInfo.normal;
		normal.y = 0f;
		m_targetBall = null;
		if (hitInfo.collider.CompareTag("Ball"))
		{
			m_targetBall = hitInfo.transform.GetComponent<PoolBall>();
			m_targetPos = hitInfo.point - normal;
		}
		if (GameManager.GType >= GameType.Standard && m_targetBall != null)
		{
			BasePlayer currentPlayer = ((PoolRulesStandard)GameManager.Rules).CurrentPlayer;
			bool flag = currentPlayer.TargetBallType == BallType.NONE && m_targetBall.ballType == BallType.BLACK;
			bool flag2 = currentPlayer.TargetBallType != BallType.NONE && currentPlayer.TargetBallType != m_targetBall.ballType;
			if (flag || flag2)
			{
				BaseUIController.cueAndLines.Forbidden();
			}
			else
			{
				BaseUIController.cueAndLines.Allow();
			}
		}
		else
		{
			BaseUIController.cueAndLines.Allow();
		}
	}

	public void Hide()
	{
		base.gameObject.SetActive(value: false);
		BaseUIController.cueAndLines.gameObject.SetActive(value: false);
	}

	public void Show()
	{
		base.gameObject.SetActive(value: true);
		BaseUIController.cueAndLines.gameObject.SetActive(value: true);
	}

	public void OnDrawGizmos()
	{
		Gizmos.color = m_GizmosColor;
		Gizmos.DrawRay(m_SidingPoint.position, -m_SidingPoint.forward);
	}
}
